/*! ******************************************************************************
 *
 * Pentaho Data Integration
 *
 * Copyright (C) 2002-2017 by Hitachi Vantara : http://www.pentaho.com
 *
 *******************************************************************************
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ******************************************************************************/

package org.pentaho.di.ui.spoon;

import org.pentaho.di.core.exception.KettlePluginException;
import org.pentaho.di.core.plugins.*;
import org.reflections.Reflections;
import org.yzbdl.lanius.core.plugins.ClassLoaderCfg;
import org.yzbdl.lanius.core.plugins.annotations.ClassLoaderAnno;
import org.yzbdl.lanius.core.plugins.metastore.LdrPluginEntity;

import java.lang.annotation.Annotation;
import java.util.Map;
import java.util.Set;

@PluginMainClassType(SpoonPluginInterface.class)
@PluginAnnotationType(SpoonPlugin.class)
public class SpoonPluginType extends BasePluginType implements PluginTypeInterface {

    private SpoonPluginType() {
        super(SpoonPlugin.class, "SPOONPLUGIN", "Spoon Plugin");

        pluginFolders.add(new PluginFolder("plugins", false, true));
    }

    private static SpoonPluginType pluginType;

    public static SpoonPluginType getInstance() {
        if (SpoonPluginType.pluginType == null) {
            SpoonPluginType.pluginType = new SpoonPluginType();
        }
        return SpoonPluginType.pluginType;

    }

    /**
     * Let's put in code here to search for the step plugins..
     */
    @Override
    public void searchPlugins() throws KettlePluginException {
        registerNatives();
        registerPluginJars();
        registerXmlPlugins();
        registerFromDb();
    }

    @Override
    protected void registerNatives() throws KettlePluginException {
        try {
            Set<Class<?>> classes = new Reflections().getTypesAnnotatedWith(SpoonPlugin.class);
            for (Class<?> clazz : classes) {
                SpoonPlugin anno = clazz.getAnnotation(SpoonPlugin.class);
                LdrPluginEntity entity = SpoonPluginType.pluginType.extractAnnotationInfo(clazz, anno);
                SpoonPluginType.pluginType.registryPlugin(entity);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void registerXmlPlugins() throws KettlePluginException {
        // TODO Auto-generated method stub
    }

    @Override
    protected String extractCategory(Annotation annotation) {
        return ((SpoonPlugin) annotation).categoryDescription();
    }

    @Override
    protected String extractDesc(Annotation annotation) {
        return ((SpoonPlugin) annotation).description();
    }

    @Override
    protected String extractID(Annotation annotation) {
        return ((SpoonPlugin) annotation).id();
    }

    @Override
    protected String extractName(Annotation annotation) {
        return ((SpoonPlugin) annotation).name();
    }

    @Override
    protected String extractImageFile(Annotation annotation) {
        return ((SpoonPlugin) annotation).image();
    }

    @Override
    protected boolean extractSeparateClassLoader(Annotation annotation) {
        return false;
    }

    @Override
    protected String extractI18nPackageName(Annotation annotation) {
        return ((SpoonPlugin) annotation).i18nPackageName();
    }

    @Override
    protected String extractSuggestion(Annotation annotation) {
        return null;
    }

    @Override
    protected String extractCasesUrl(Annotation annotation) {
        return null;
    }

    @Override
    protected String extractForumUrl(Annotation annotation) {
        return null;
    }

    @Override
    public void addExtraClasses(Map<Class<?>, String> classMap, Class<?> clazz, Annotation annotation) {
    }

//  @Override
//  protected String extractDocumentationUrl( Annotation annotation ) {
//    return null;
//  }
//
//  @Override
//  protected String extractCasesUrl( Annotation annotation ) {
//    return null;
//  }
//
//  @Override
//  protected String extractForumUrl( Annotation annotation ) {
//    return null;
//  }

    @Override
    protected String extractClassLoaderGroup(Annotation annotation) {
        return ((SpoonPlugin) annotation).classLoaderGroup();
    }

    @Override
    protected String extractVersion(Annotation annotation) {
        return ((SpoonPlugin) annotation).version();
    }

    @Override
    protected boolean extractEnterprise(Annotation annotation) {
        return ((SpoonPlugin) annotation).enterprise();
    }

    @Override
    protected ClassLoaderCfg extractClassLoaderAnno(Annotation annotation) {
        ClassLoaderAnno clAnno = ((SpoonPlugin) annotation).classLoader();
        ClassLoaderCfg clVo = new ClassLoaderCfg();
        clVo.setIsSeparateClassLoaderNeeded(clAnno.isSeparateClassLoaderNeeded());
        clVo.setUserDefinedGroup(clAnno.userDefinedGroup());
        clVo.setFolderBasedGroup(clAnno.folderBasedGroup());
        return clVo;
    }


}
